﻿using System;
using System.Collections.Generic;
using System.Windows.Browser;
using System.ServiceModel;
using System.Text;
using System.ServiceModel.Description;
using System.Windows;
using BingMapBrowser.CrmSdk;

namespace BingMapBrowser
{
	internal static class SilverlightUtility
	{
		public static bool IsDebug = false;
		public static string ConvertToString(Exception exception)
		{
			string prefix = "";

			StringBuilder sb = new StringBuilder();
			while (null != exception)
			{
				sb.Append(prefix);
				sb.AppendLine(exception.Message);
				sb.AppendLine(exception.StackTrace);

				prefix = "Innner Exception: ";
				exception = exception.InnerException;
			}

			return sb.ToString();
		}

		public static string BingMapKey()
		{
			String bingUrl = (String)HtmlPage.Window.Invoke("GetBingMapKey");
			return bingUrl;
		}

		public static string GetConfigFile()
		{
			string qs = (String)HtmlPage.Window.Invoke("qs", "data");
			string[] parameters = qs.Split(new string[] {";"}, StringSplitOptions.RemoveEmptyEntries);
			string configFile = null;
			foreach (string param in parameters)
			{
				if (param.Equals("debug", StringComparison.OrdinalIgnoreCase))
				{
					IsDebug = true;
				}
				else
				{
					configFile = param;
				}
			}
			return configFile;
		}

		public static IOrganizationService GetSoapService()
		{
			Uri serviceUrl = CombineUrl(GetServerBaseUrl(), "XRMServices/2011/Organization.svc/web");

			BasicHttpBinding binding = new BasicHttpBinding(Uri.UriSchemeHttps == serviceUrl.Scheme
				? BasicHttpSecurityMode.Transport : BasicHttpSecurityMode.TransportCredentialOnly);
			binding.MaxReceivedMessageSize = int.MaxValue;
			binding.MaxBufferSize = int.MaxValue;
			binding.SendTimeout = TimeSpan.FromMinutes(2);

			return new CrmSdk.MyOrganizationServiceClient(binding, new EndpointAddress(serviceUrl));
		}

		public static Uri GetServerBaseUrl()
		{
			String serverUrl = (String)HtmlPage.Window.Invoke("getServerUrl");
			return new Uri(serverUrl);
		}

		//Should be thread safe.
		public static void Trace(string message)
		{
			if (IsDebug)
			{
				MessageBox.Show(message);
			}

		}

		/// <summary>
		/// Combines a URI with a relative URI
		/// </summary>
		/// <param name="baseValue">Base (absolute) URI</param>
		/// <param name="value">Relative URI that is to be used</param>
		/// <returns>Combined URI</returns>
		public static Uri CombineUrl(Uri baseValue, string value)
		{
			if (null == baseValue)
			{
				throw new ArgumentNullException("baseValue");
			}
			else if (string.IsNullOrEmpty(value))
			{
				return baseValue;
			}

			//Ensure that a double '/' is not being added
			string newValue = baseValue.AbsoluteUri;
			if (!newValue.EndsWith("/", StringComparison.Ordinal))
			{
				//Check if there is a character at the beginning of value
				if (!value.StartsWith("/", StringComparison.Ordinal))
				{
					newValue += "/";
				}
			}
			else if (value.StartsWith("/", StringComparison.Ordinal))
			{
				value = value.Substring(1);
			}

			//Create the combined URL
			return new Uri(newValue + value);
		}

		#region Private Methods
		private static ScriptObject GetContext()
		{
			ScriptObject xrmProperty = (ScriptObject)HtmlPage.Window.GetProperty("Xrm");
			if (null == xrmProperty)
			{
				//It may be that the global context should be used
				ScriptObject globalContext = (ScriptObject)HtmlPage.Window.Eval("if (typeof GetGlobalContext != 'undefined') { return GetGlobalContext(); } else { return null; }");
				if (null == globalContext)
				{
					throw new InvalidOperationException("Property \"Xrm\" is null and the Global Context is not available.");
				}

				return globalContext;
			}

			ScriptObject pageProperty = (ScriptObject)xrmProperty.GetProperty("Page");
			if (null == pageProperty)
			{
				throw new InvalidOperationException("Property \"Xrm.Page\" is null");
			}

			ScriptObject contextProperty = (ScriptObject)pageProperty.GetProperty("context");
			if (null == contextProperty)
			{
				throw new InvalidOperationException("Property \"Xrm.Page.context\" is null");
			}

			return contextProperty;
		}
		#endregion
	}
}
